//
//  DrawImageView.swift
//  SmartPenSwift
//
//  Created by tql on 2021/2/21.
//

import UIKit
import SmartPenSDK


public protocol ReplayDelegate : NSObjectProtocol {
    func  StopReplayBeacuseNoData()
    func  ReplayProgress(_ currentIndex : Int,_ total : Int )
    func  replayEnd()
}

let B5_WIDTH : Float = 119.44
let B5_HEIGHT : Float = 168
let KELAMAYI_WIDTH : Float = 168
let KELAMAYI_HEIGHT : Float = 168

let A4_WIDTH : Float = 168
let A4_HEIGHT : Float = 168

let Copybook_WIDTH : Float = 168
let Copybook_HEIGHT : Float = 168

let LCDScreen_WIDTH : Float = 168
let LCDScreen_HEIGHT : Float = 168




class DrawImageView: UIImageView {

    weak open var delegate: ReplayDelegate?
    var gCurPageID : Int = -1
    var isBackground : Bool = false
    var drawPointZ : Int = 0
    var drawpointX : CGFloat = 0
    var drawpointY : CGFloat = 0
    var redoSpeed : Float = 0
    var firstXy : Bool = false
    
    var gOffsetX : Float = 0
    var gOffsetY : Float = 0
    
    var  gScale : Float = 0
    var  gpointX : Float = B5_WIDTH
    var gpointY : Float = B5_HEIGHT
    var gWidth : Int = 1
    var ipl : Int = 0
    var iLimit : Int = 0
    var isReplay : Bool = false
    var maxPageNumber : Int = 0
    
    //NSMutableString *dataStr;
    var insideNeedStroke = false
    var _needStroke : Bool {
        get{
            return insideNeedStroke
        }set{
            debugPrint("setvalue:_needStroke = \(newValue)")
            insideNeedStroke = newValue
            if insideNeedStroke {
                self.myView.isHidden = false
                self.notStrokeView.isHidden = true
            }else{
                self.myView.isHidden = true
                self.notStrokeView.isHidden = false
            }
        }
    }
    lazy var myView : DrawGLKView = {
        let view : DrawGLKView = DrawGLKView.init(frame: self.bounds)
        view.strokeColor = .black
        
        return view
    }()
    
    lazy var notStrokeView : MyDrawView = {
        let view : MyDrawView = MyDrawView.init(frame: self.bounds)
        view.strokeColor = .black
        view.delegate = self
        
        return view
    }()
    
    var imageName : String = ""
    var lineColor : UIColor = .black
    var timer : Timer?
    lazy var dotBackgroundArray : NSMutableArray = NSMutableArray()
    lazy var allPageDictionary : NSMutableDictionary = NSMutableDictionary()
    lazy var allBookDictionary : NSMutableDictionary = NSMutableDictionary()
    lazy var xRecognizeString : NSMutableString = NSMutableString()
    lazy var yRecognizeString : NSMutableString = NSMutableString()
    var currentBookID : Int = -1
    var currenSectionID : Int = -1
    var isLCDScreen : Bool  = false
    
    override init(frame: CGRect) {
         super.init(frame: frame)
        _needStroke = UserDefaults.standard.bool(forKey: "kStrokePen")
        self.createDrawView()
        self.createArray()
        self.initData()
        self.updateBackgroudImageView()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    func createDrawView() -> Void {
        self.isUserInteractionEnabled = true
        self.image = UIImage.init(named: "ben0.png")
        
        
        self.addSubview(self.myView)
        self.myView.frame = self.bounds
        self.addSubview(self.notStrokeView)
        self.notStrokeView.frame = self.bounds
        if insideNeedStroke {
            self.myView.isHidden = false
            self.notStrokeView.isHidden = true
        }else{
            self.myView.isHidden = true
            self.notStrokeView.isHidden = false
        }

        
        NotificationCenter.default.addObserver(self, selector: #selector(enterBackground), name: NSNotification.Name(rawValue: "enterBackground"), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(enterForeground), name: NSNotification.Name(rawValue: "enterForeground"), object: nil)

        
    }
    @objc func enterBackground() -> Void {
        isBackground = true
    }
    @objc func enterForeground(){
        isBackground = false
    }
    
    func createArray() -> Void {
        
    }
    func initData() -> Void {
        gOffsetX = 0
        gOffsetY = 0
        gScale = 1
        self.gCurPageID = -1
        gWidth = 1
        isReplay = false
        firstXy = false
        maxPageNumber = 0
        isBackground = false
        self.lineColor = .black
        self.currentBookID = -1
        isLCDScreen = false
        
    }
    
    
    func processEachDot(_ dot : Dot,_ isoffline : Bool) -> Void {
        
        guard dot != nil else {
            return
        }
        if isBackground {
            dotBackgroundArray.add(dot)
            return
        }
        isReplay = false
        drawPointZ = Int(dot.force)
        
        drawpointX = CGFloat(Float(dot.x) + Float(dot.fx) / 100.0)
        drawpointY = CGFloat(Float(dot.y) + Float(dot.fy) / 100.0)
        
        if insideNeedStroke {
            myView.strokeColor = self.lineColor
        }else{
            notStrokeView.strokeColor = self.lineColor
        }
        
        
        if drawPointZ > 0 {
            if firstXy == false {
                firstXy = true
                
                if drawpointX <= 0 || drawpointY <= 0 {
                    return
                }
                dot.bookID = dot.sectionID * 25600 + dot.ownerID * 256 + dot.bookID
                if dot.bookID != currentBookID {
                    currentBookID = Int(dot.bookID)
                    gCurPageID = -1
                    
                    let bookString = "\(currentBookID)"
                    var bookDic = allBookDictionary.object(forKey: bookString)
                    if bookDic == nil {
                        bookDic = NSMutableDictionary.init()
                        allBookDictionary.setObject(bookDic, forKey: bookString as NSCopying)
                    }
                    
                    allPageDictionary = bookDic as! NSMutableDictionary
                    self.updateBackgroudImageView()
                    self.getDrawPoint()
                }else{
                    self.getDrawPoint()
                }
                if dot.pageID != gCurPageID {
                    gCurPageID = Int(dot.pageID)
                    redoSpeed = 0
                    let pageString = imageName + "\(gCurPageID)"
                    var pageArr : NSMutableArray? = allPageDictionary.object(forKey: pageString) as! NSMutableArray?
                    if pageArr == nil {
                        pageArr = NSMutableArray.init()
                        allPageDictionary.setObject(pageArr, forKey: pageString as NSCopying)
                    }
                    self.setBackgroundImage(Int(dot.pageID))
                    self.drawExistingStroke(gCurPageID)
                }
                
                if insideNeedStroke {
                    myView.startWithScale(gScale, gOffsetX, gOffsetY, gWidth, Float(drawpointX),Float( drawpointY), Int(dot.force))
                }else{
                    notStrokeView.startWithScale(gScale, gOffsetX, gOffsetY, gWidth, Float(drawpointX),Float( drawpointY), Int(dot.force))
                }
                //            myView.startWithScale(gScale, gOffsetX, gOffsetY, gWidth, drawpointX, drawpointY, dot.force)
                
                
                let dotStruct : DotStruct = DotStruct.init(DX: Float(drawpointX), DY: Float(drawpointY), DT: dot.type.rawValue, PageID: Int(gCurPageID), DF: Int(drawPointZ), PW: gWidth, LC: lineColor, TL: Int(dot.timelong))
                
                let pageKey = imageName + "\(gCurPageID)"
                
                let pageArr : NSMutableArray = allPageDictionary.object(forKey: pageKey) as! NSMutableArray
                pageArr.add(dotStruct)
                
                
            }else{
                self.getDrawPoint()
                if drawpointX <= 0 || drawpointY <= 0 {
                    return
                }
                if insideNeedStroke {
                    myView.moveWithScale(gScale, gOffsetX, gOffsetY, gWidth, Float(drawpointX),Float( drawpointY), Int(dot.force))
                }else{
                    notStrokeView.moveWithScale(gScale, gOffsetX, gOffsetY, gWidth, Float(drawpointX),Float( drawpointY), Int(dot.force))
                }
                let dotStruct : DotStruct = DotStruct.init(DX: Float(drawpointX), DY: Float(drawpointY), DT: dot.type.rawValue, PageID: Int(gCurPageID), DF: Int(drawPointZ), PW: gWidth, LC: lineColor, TL: Int(dot.timelong))
                
                let pageKey = imageName + "\(gCurPageID)"
                
                let pageArr : NSMutableArray = allPageDictionary.object(forKey: pageKey) as! NSMutableArray
                pageArr.add(dotStruct)
                
            }
        }else{
            self.getDrawPoint()
            if dot.type == .PEN_UP {
                if drawpointX <= 0 || drawpointY <= 0 {
                    return
                }
                firstXy = false
                let dotStruct : DotStruct = DotStruct.init(DX: Float(drawpointX), DY: Float(drawpointY), DT: dot.type.rawValue, PageID: Int(gCurPageID), DF: Int(drawPointZ), PW: gWidth, LC: lineColor, TL: Int(dot.timelong))
                
                let pageKey = imageName + "\(gCurPageID)"
                
                let pageArr : NSMutableArray = allPageDictionary.object(forKey: pageKey) as! NSMutableArray
                pageArr.add(dotStruct)
                if insideNeedStroke {
                    
                    myView.moveWithScale(gScale, gOffsetX, gOffsetY, gWidth, Float(drawpointX),Float( drawpointY), Int(dot.force))
                    myView.end()
                }else{
                    
                    notStrokeView.endWithScale(gScale, gOffsetX, gOffsetY, gWidth, Float(drawpointX),Float( drawpointY), Int(dot.force))
                    notStrokeView.end()
                }
                
                drawpointX = 0
                drawpointY = 0
            }
        }
    }
    func getDrawPoint() -> Void {
        self.getPointPageWidth(Int(gpointX), Int(gpointY))
    }
    func getPointPageWidth(_ width : Int , _ pageHeight : Int){
        let VWidth = self.bounds.size.width
        let Vheight = self.bounds.size.height
        drawpointX = drawpointX * VWidth
        drawpointX = drawpointX / CGFloat(width)
        drawpointY = drawpointY * Vheight
        drawpointY = drawpointY / CGFloat(pageHeight)
    }
    func setBackgroundImage(_ imageID : Int) -> Void {
        
        var imagenameString = imageName + "\(imageID)"
        
        var image : UIImage? = UIImage.init(named: imagenameString)
        if image == nil {
            imagenameString = imageName + "0"
            image = UIImage.init(named: imagenameString)!
        }
        let data : Data = image!.pngData()!
        
        self.image = UIImage.init(data: data)
        
        let imgOriginW = image!.size.width
        let imgOriginH = image!.size.height
        
        if imgOriginW > 0 && imgOriginH > 0 {
            
            let height = (kScreenWidth - 20 ) * imgOriginH / imgOriginW
            let rect : CGRect = CGRect(x: 10, y: (kScreenHeight - NavBarHeight - TabBarHeight - height - 60) / 2.0, width: kScreenWidth - 20, height: height)
            self.frame = rect
        }
        
    }
    
    func clearPath() -> Void {
        debugPrint("clearpath::::")
        if gCurPageID < 0 {
            return
        }
        let pageKey = imageName + "\(gCurPageID)"
        let pageArray = allPageDictionary.object(forKey: pageKey) as! NSMutableArray
        pageArray.removeAllObjects()
        self.setBackgroundImage(gCurPageID)
        if insideNeedStroke {
            myView.erase()
        }else{
            notStrokeView.erase()
        }
        
    }
    func changeLineWidth(_ width : Float) -> Void {
        gWidth = Int(width)
        isReplay = false
    }
    func changeLineColor(_ color : UIColor) -> Void {
        lineColor = color
        isReplay = false
        
        self.myView.strokeColor = color
        self.notStrokeView.strokeColor = color
//        lineColor = .red
    }
    func rePlay(_ speedLevel : Int) -> Void {
        NSLog("not do now ", "")
    }
    func pauseReplay(_ isPause : Bool) -> Void {
        debugPrint(#function)
        NSLog("not do now ", "")

    }
    
    func changeBookSize(_ dataType : Int) -> Void {
        self.clearPath()
        self.initData()
        self.image = UIImage.init(named: "ben0.png")
        imageName = "page"
        maxPageNumber = 64
    }
    func updateBackgroudImageView() -> Void {
        if currentBookID == 22628 {
            maxPageNumber = 64
            imageName = "kelamayi_Page"
            dotBackgroundArray = NSMutableArray.init()
            gpointX = KELAMAYI_WIDTH
            gpointY = KELAMAYI_HEIGHT
            
        }else if currentBookID == 100 {
            maxPageNumber = 64
            imageName = "page"
            dotBackgroundArray = NSMutableArray.init()
            gpointX = B5_WIDTH
            gpointY = B5_HEIGHT
        }else if currentBookID == 0 {
            maxPageNumber = 64
            imageName = "question_page"
            dotBackgroundArray = NSMutableArray.init()
            gpointX = A4_WIDTH
            gpointY = A4_HEIGHT
        }else if currentBookID == 256000 {
            maxPageNumber = 92
            imageName = "Copybook"
            dotBackgroundArray = NSMutableArray.init()
            gpointX = Copybook_WIDTH
            gpointY = Copybook_HEIGHT
        }else   {
            maxPageNumber = 64
            imageName = "page"
            dotBackgroundArray = NSMutableArray.init()
            gpointX = B5_WIDTH
            gpointY = B5_HEIGHT
        }
        
    }
    
    func drawExistingStroke(_ PageID : Int) -> Void {
        if insideNeedStroke {
            myView.erase()
        }else{
            notStrokeView.erase()
        }
        
        
        let key = imageName + "\(gCurPageID)"
        let pageArr : NSMutableArray = allPageDictionary.object(forKey: key) as! NSMutableArray
        if pageArr.count == 0 {
            return
        }
        for i : Int in 0..<pageArr.count {
            let dot : DotStruct = pageArr.object(at: i) as! DotStruct
            
            if insideNeedStroke {
                myView.strokeColor = dot.lineColor
                if dot.drawType == 0 {
                    myView.startWithScale(gScale, gOffsetX, gOffsetY, dot.penWidth, dot.drawPointX, dot.drawPointY, dot.drawForce)
                }else if dot.drawType == 1 {
                    myView.moveWithScale(gScale, gOffsetX, gOffsetY, dot.penWidth, dot.drawPointX, dot.drawPointY, dot.drawForce)
                }else{
                    myView.moveWithScale(gScale, gOffsetX, gOffsetY, dot.penWidth, dot.drawPointX, dot.drawPointY, dot.drawForce)
                    myView.end()
                }
            }else{
                notStrokeView.strokeColor = dot.lineColor
                if dot.drawType == 0 {
                    notStrokeView.startWithScale(gScale, gOffsetX, gOffsetY, dot.penWidth, dot.drawPointX, dot.drawPointY, dot.drawForce)
                }else if dot.drawType == 1 {
                    notStrokeView.moveWithScale(gScale, gOffsetX, gOffsetY, dot.penWidth, dot.drawPointX, dot.drawPointY, dot.drawForce)
                }else{
                    notStrokeView.endWithScale(gScale, gOffsetX, gOffsetY, dot.penWidth, dot.drawPointX, dot.drawPointY, dot.drawForce)
                    notStrokeView.end()
                }
            }
           
        }
        
    }
    func getgetcognizeArray() -> Array<Any> {
        
        return []
    }
    func getLocalRcognizeArray() -> Array<Any> {
        
        return []
    }

    func changeBookLCDScreen() -> Void {
        isLCDScreen = true
        imageName = "341557544654_.pic_hd0"
        self.image = UIImage.init(named: "341557544654_.pic_hd0")
        maxPageNumber = 1
    }
    func changeDrawViewWith(ifNeedStroke needStroke : Bool) -> Void {
        self._needStroke = needStroke
    }
    func redrawCurrentData() -> Void {
        self.drawExistingStroke(gCurPageID)
    }
    
    override func delete(_ sender: Any?) {
        isReplay = false
        allPageDictionary = NSMutableDictionary.init()
        myView.removeFromSuperview()
        notStrokeView.removeFromSuperview()
    }
}

extension DrawImageView : getDrawImageDelegate{
    func getDrawImage(_ drawImage: UIImage?) {
     
        self.snapshotViewFromRect(self.bounds, UIEdgeInsets.init(top: 0, left: 0, bottom: 0, right: 0))
    }
    func snapshotViewFromRect(_ rect : CGRect, _ capInsets : UIEdgeInsets) -> Void {
        
        UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.main.scale)
        let context = UIGraphicsGetCurrentContext()!
        context.translateBy(x: rect.minX, y: rect.minY)
        self.layer.render(in: context)
        
        let snapshotImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        context.flush()
        UIGraphicsEndImageContext()
        let image : UIImage = snapshotImage.resizableImage(withCapInsets: capInsets)
        self.image = image
    }
}
